package com.qingmeng.apiclientsdk.client;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.qingmeng.apiclientsdk.dto.RequestParams;
import com.qingmeng.apiclientsdk.entry.MonthDay;
import com.qingmeng.apiclientsdk.entry.User;
import com.qingmeng.apicommon.common.BaseResponse;
import com.qingmeng.apicommon.common.ResultUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import static com.qingmeng.apiclientsdk.utils.SignUtils.getSign;

/**
 * 接口调用客户端
 * @author  清梦
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApiClient {
    private static final String GATEWAY_HOST = "http://localhost:8090/api";

    // accessKey
    private String accessKey;

    // secretKey
    private String secretKey;

    /**
     * 根据 methodName 调用相应的方法并返回 BaseResponse
     *
     * @param methodName 方法名
     * @param params     请求参数
     * @return BaseResponse 结果
     */
    public BaseResponse<?> invokeMethod(String methodName, RequestParams<?> params) {
        try {
            // 获取方法对象及其参数类型
            Method method = getDeclaredMethodByNameAndParams(methodName, params.getBody());
            Object result = method.invoke(this, params.getBody());

            return ResultUtils.success(result);
        } catch (Exception e) {
            return ResultUtils.error(40010,"Error invoking interface: " + methodName + ". Error: " + e.getMessage());
        }
    }

    private Method getDeclaredMethodByNameAndParams(String methodName, Object body) throws NoSuchMethodException {
        Class<?>[] parameterTypes = new Class<?>[]{body.getClass()};
        return this.getClass().getDeclaredMethod(methodName, parameterTypes);
    }

    // 调用接口---------------------------------------------------------
    public String getNameByGet(String name) {
        //可以单独传入http参数，这样参数会自动做URL编码，拼接在URL中
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", name);
        String string = null;
        try {
           string = HttpUtil.get(GATEWAY_HOST + "/name/get", paramMap);
        }catch (Exception e){
           throw new RuntimeException("接口调用异常" + e);
        }
        return string;
    }
    public String getNameByPost(String name) {

        //可以单独传入http参数，这样参数会自动做URL编码，拼接在URL中
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", name);
        // 调用接口
        String string = null;
        try {
            string = HttpUtil.post(GATEWAY_HOST + "/name/post", paramMap);
        }catch (Exception e){
            throw new RuntimeException("接口调用异常" + e);
        }
        //响应结果
        return string;
    }
    public String getNameByJson(User user){

        String json = JSONUtil.toJsonStr(user);
        HttpResponse httpResponse = null;
        try {
            httpResponse = HttpRequest.post(GATEWAY_HOST + "/name/json")
                  .addHeaders(getHeaders(json))
                  .body(json)
                  .execute();
        } catch (Exception e) {
            throw new RuntimeException("接口调用异常" + e);
        }
        if (!httpResponse.isOk()){
            throw new RuntimeException("请求失败");
        }
        return httpResponse.body();
    }

    /**
     * 历史上的今天
     * @param monthDay
     * @return
     */
    public String getDayHistory(MonthDay monthDay){
        String json = JSONUtil.toJsonStr(monthDay);
//        Map<String, Object> param = new HashMap<String, Object>();
//        param.put("month", monthDay.getMonth());
//        param.put("day", monthDay.getDay());

        HttpResponse httpResponse = null;
        try {
            httpResponse = HttpRequest.post(GATEWAY_HOST + "/day/history")
                    .addHeaders(getHeaders(json))
//                    .form(param)
                    .body(json)
                    .execute();
        } catch (Exception e) {
            throw new RuntimeException("接口调用异常" + e);
        }
        if (!httpResponse.isOk()){
            throw new RuntimeException("请求失败");
        }
        return httpResponse.body();
    }

    /**
     *  获取请求头
     *  /day/wrapper
     * @param body
     * @return
     * @throws UnsupportedEncodingException
     */
    private Map<String , String> getHeaders(String body) throws UnsupportedEncodingException {
        Map<String, String> headerMap = new HashMap<>();
        // 设置AK
        headerMap.put("accessKey", accessKey);
        // 设置SK （不能直接发送密钥）
//        headerMap.put("secretKey", secretKey);
        // 设置请求体
        // 为防止中文乱码，这里对body重新编码
        String newBody = URLEncoder.encode(body, "utf-8");
        headerMap.put("body", newBody);
        // 设置nonce 随机数
        headerMap.put("nonce", RandomUtil.randomNumbers(4));
        // 设置时间戳
        headerMap.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        // 设置签名sign
        headerMap.put("sign", getSign(newBody, secretKey));
        return headerMap;
    }


}
